package com.banksoft.cps.service.impl;

import com.banksoft.cps.bean.Company;
import com.banksoft.cps.bean.FileInfo;
import com.banksoft.cps.bean.common.ServiceException;
import com.banksoft.cps.bean.query.CompanyQuery;
import com.banksoft.cps.bean.warpper.CompanyRegisterWarpper;
import com.banksoft.cps.bean.warpper.CompanyWarpper;
import com.banksoft.cps.constants.ErrorConstant;
import com.banksoft.cps.constants.WebConstant;
import com.banksoft.cps.dao.CompanyDao;
import com.banksoft.cps.dao.FileInfoDao;
import com.banksoft.cps.enums.UserType;
import com.banksoft.cps.service.CompanyService;
import com.banksoft.cps.util.CacheUtil;
import com.banksoft.cps.util.StrGenerator;
import com.banksoft.cps.util.UUIDFactory;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by rongzhao.zhu on 2017/12/22.
 */
@Service
public class CompanyServiceImpl implements CompanyService {

    @Autowired
    CompanyDao companyDao ;
    @Autowired
    FileInfoDao fileInfoDao;

    @Override
    public List<CompanyWarpper> list(CompanyQuery query) {
        List<Company> companies = companyDao.list(query);
        if(companies.isEmpty()){
            return null;
        }
        List<String> fileIds = new ArrayList<>();
        companies.stream().forEach(e->{
            String regulation = e.getRegulation();
            if(StringUtils.isNotBlank(regulation)){
                String[] fileIdsArray = regulation.split(",");
                fileIds.addAll(Arrays.asList(fileIdsArray)) ;
            }
        });
        Map<String,FileInfo> fileInfoMap ;
        if(!fileIds.isEmpty()){
            List<FileInfo> fileInfos = fileInfoDao.queryFiles(fileIds);
            fileInfoMap = fileInfos.stream().collect(Collectors.toMap(e->e.getId(), e->e));
        }else {
            fileInfoMap = new HashMap<>();
        }

        return companies.stream().map(e->{
            CompanyWarpper warpper = new CompanyWarpper();
            BeanUtils.copyProperties(e,warpper);
            String regulation = e.getRegulation();
            if(StringUtils.isNotBlank(regulation)){
                List<FileInfo> _flieInfoList  = new ArrayList<>();
                warpper.setFileInfoList(_flieInfoList);
                String[] fileIdsArray = regulation.split(",");
                for(String _id :fileIdsArray){
                    FileInfo _fileInfo =  fileInfoMap.get(_id);
                    if(_fileInfo !=null){
                        _flieInfoList.add(_fileInfo) ;
                    }

                }

            }
            return warpper;
        }).collect(Collectors.toList());
    }

    @Override
    public long count(CompanyQuery query) {
        return companyDao.count(query);
    }

    @Override
    public void save(Company company) {
        if(StringUtils.isNotBlank(company.getId())){
            companyDao.update(company);
        }else {
            company.setId(UUIDFactory.random());
            companyDao.insert(company);
        }
    }

    @Override
    public CompanyWarpper findById(String id) {
        if(StringUtils.isNotBlank(id)){
            CompanyQuery query = new CompanyQuery();
            query.setId(id);
            List<Company> companyList = companyDao.list(query);
            if(!companyList.isEmpty()){
                Company bean = companyList.get(0);
                CompanyWarpper warpper = new CompanyWarpper();
                BeanUtils.copyProperties(bean,warpper);
                String files = bean.getRegulation();
                if (StringUtils.isNotBlank(files)) {
                    String[] fileIdsArray = files.split(",");
                    List fileIds = Arrays.asList(fileIdsArray);
                    List fileInfos = fileInfoDao.queryFiles(fileIds);
                    warpper.setFileInfoList(fileInfos);
                }
                return warpper;
            }
        }

        return null;
    }

    @Override
    public Company login(String account, String password) throws ServiceException {
        if(StringUtils.isBlank(account)){
            throw new ServiceException(ErrorConstant.ec_param_null,ErrorConstant.em_user_account_null);
        }
        if(StringUtils.isBlank(password)){
            throw new ServiceException(ErrorConstant.ec_param_null,ErrorConstant.em_user_password_null);
        }
        Company company = companyDao.findByAccount(account);
        if(company == null ){
            throw new ServiceException(ErrorConstant.ec_result_null,ErrorConstant.em_user_null);
        }
        if(!company.getPassword().equals(password)){
            throw new ServiceException(ErrorConstant.ec_param_error,ErrorConstant.em_password_error);
        }
        String token =  token(company);
        Map<String,String> cookieMap = new HashMap<>();
        cookieMap.put(WebConstant.cookieToken,token);
        cookieMap.put(WebConstant.cookieFake, StrGenerator.generateRandomStr(32));
        cookieMap.put(WebConstant.cookieName, StrGenerator.EncoderByMd5(company.getName()));
        company.setCookieMap(cookieMap);
        company.setType(UserType.company.name());
        CacheUtil.cache(token,company);
        return company;
    }

    @Override
    public void logout(String token) {
        CacheUtil.remove(token);
    }

    @Override
    public void updatePassword(String id, String oldPassword, String newPassword) throws ServiceException {
        Company bean = companyDao.findById(id);
        if(!bean.getPassword().equals(oldPassword)){
            throw new ServiceException(ErrorConstant.ec_param_error,ErrorConstant.em_password_error);
        }
        bean.setPassword(newPassword);
        companyDao.update(bean);
    }

    @Override
    public void deleteByIds(String[] ids) {
        companyDao.deleteByIds(ids);
    }

    @Override
    public void updateStatus(String id, String status) {
        Company company = companyDao.findById(id);
        company.setStatus(status);
        companyDao.update(company);
    }
}
